package com.leyou.cart.filter;


import com.leyou.auth.entiy.UserInfo;
import com.leyou.auth.utils.JwtUtils;
import com.leyou.cart.config.JwtProperties;
import com.leyou.common.utils.CookieUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Vector;

/**
 * 自定义拦截器LoginInterceptor；继承HandlerInterceptorAdapter；并重写前置方法和完成方法；
 * 目的：解耦，把公共代码（由于每次否要获取token中的用户信息，所以把获取用户信息放到拦截器中完成）
 * 放到前置方法；并把对象放到一个线程对象域中（目的：存放登入的用户信息；只要满足俩条都可以作为域对象存放；满足支持多线程并且并且线程安全
 * Vector），每次都从线程域中获取用户信息:完成后把存放的用户信息删除
 */
public class LoginInterceptor extends HandlerInterceptorAdapter {

    private JwtProperties jwtProperties;
    // 定义一个线程域，存放登录用户
    private static final ThreadLocal<UserInfo> t1=new ThreadLocal<>();

    public LoginInterceptor(JwtProperties jwtProperties){
        this.jwtProperties=jwtProperties;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    //前置拦截：获取token，解析userInfo,存入线程池
        //获取token
        String token = CookieUtils.getCookieValue(request, jwtProperties.getCookieName());
        if (StringUtils.isBlank(token)){
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
            return false;
        }
        try {
            //解析token
            UserInfo userInfo = JwtUtils.getInfoFromToken(token, jwtProperties.getPublicKey());
            t1.set(userInfo);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            // 抛出异常，证明未登录,返回401
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
            return false;
        }


    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        t1.remove();
        super.afterCompletion(request, response, handler, ex);
    }

    public static  UserInfo getLoginUser(){
        return t1.get();
    }
}
